package cn.ug.pay.web.controller;

import cn.ug.account.bean.DataDictionaryBean;
import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.Order;
import cn.ug.bean.base.Page;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.config.Config;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.login.LoginHelper;
import cn.ug.enums.ProductTypeEnum;
import cn.ug.enums.RateKeyEnum;
import cn.ug.feign.DataDictionaryService;
import cn.ug.feign.MemberUserService;
import cn.ug.feign.ProductService;
import cn.ug.feign.RateSettingsService;
import cn.ug.member.bean.MemberDetailBean;
import cn.ug.member.bean.response.MemberUserBean;
import cn.ug.member.mq.MemberPasswordStatusMQ;
import cn.ug.mq.DelayMessagePostProcessor;
import cn.ug.pay.bean.*;
import cn.ug.pay.bean.type.PayType;
import cn.ug.pay.bean.type.ProductOrderPayStatus;
import cn.ug.pay.service.ProductOrderService;
import cn.ug.product.bean.response.ProductFindBean;
import cn.ug.util.BigDecimalUtil;
import cn.ug.util.ExportExcelUtil;
import cn.ug.util.PaginationUtil;
import cn.ug.util.UF;
import cn.ug.web.controller.BaseController;
import cn.ug.web.controller.ExportExcelController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;

import static cn.ug.config.QueueName.QUEUE_MEMBER_PASSWORD_STATUS_DELAY;
import static cn.ug.util.ConstantUtil.GOLD_WEIGHT_RANGE;
import static cn.ug.util.ConstantUtil.NORMAL_DATE_FORMAT;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * 定期投资管理
 * @author kaiwotech
 */
@RestController
@RequestMapping("productOrder")
public class ProductOrderController extends BaseController {
    @Resource
    private ProductOrderService productOrderService;
    @Resource
    private MemberUserService memberUserService;
    @Autowired
    private ProductService productService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private RateSettingsService rateSettingsService;
    @Resource
    private Config config;
    @Autowired
    private DataDictionaryService dataDictionaryService;

    @GetMapping(value = "/everyday/buy/list")
    public SerializeObject<DataTable<EverydayBuyGoldBean>> listEverydayBuyGoldRecords(@RequestHeader String accessToken, Page page, String payDate) {
        payDate = UF.toString(payDate);
        List<EverydayBuyGoldBean> data = productOrderService.queryEverydayBuyGoldRecords(payDate);
        if (data != null && data.size() > 0) {
            page.setTotal(data.size());
            if (page.getPageSize() > 0) {
                data = data.stream().skip((PaginationUtil.getPage(page.getPageNum())-1) * page.getPageSize()).limit(page.getPageSize()).collect(Collectors.toList());
            }
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<EverydayBuyGoldBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), data));
        } else {
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<EverydayBuyGoldBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<EverydayBuyGoldBean>()));
        }
    }

    @GetMapping(value = "/everyday/buy/record/list")
    public SerializeObject<DataTable<BuyGoldRecordBean>> listBuyGoldRecords(@RequestHeader String accessToken, Page page, String payDate) {
        payDate = UF.toString(payDate);
        int total = productOrderService.countBuyGoldRecord(payDate);
        page.setTotal(total);
        if (total > 0) {
            List<BuyGoldRecordBean> list = productOrderService.queryBuyGoldRecord(payDate, PaginationUtil.getOffset(page.getPageNum(), page.getPageSize()), PaginationUtil.getPageSize(page.getPageSize()));
            for (BuyGoldRecordBean bean : list) {
                if (StringUtils.isNotBlank(bean.getMobile())) {
                    bean.setMobile(StringUtils.substring(bean.getMobile(), 0, 3) +"****"+ StringUtils.substring(bean.getMobile(), 7));
                }
            }
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<BuyGoldRecordBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<BuyGoldRecordBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<BuyGoldRecordBean>()));
    }

    @GetMapping(value = "/everyday/buy/record/export")
    public void exportData(HttpServletResponse response, String payDate) {
        payDate = UF.toString(payDate);
        List<BuyGoldRecordBean> list = productOrderService.queryBuyGoldRecord(payDate, 0, 0);
        if(list != null && list.size() > 0){
            String[] columnNames = { "序号", "操作时间","手机号", "用户姓名", "产品名称", "购买克重（克）", "购买时金价（元/克）", "支付金额（元）"};
            String [] columns = {"index",  "payTime", "mobile", "name", "productName", "payGram", "goldPrice", "payAmount"};
            String fileName = "买金核算详表-"+payDate;
            int index = 1;
            for (BuyGoldRecordBean bean : list) {
                if (StringUtils.isNotBlank(bean.getMobile())) {
                    bean.setMobile(StringUtils.substring(bean.getMobile(), 0, 3) +"****"+ StringUtils.substring(bean.getMobile(), 7));
                }
                bean.setIndex(index);
                index++;
            }
            ExportExcelController<BuyGoldRecordBean> export = new ExportExcelController<BuyGoldRecordBean>();
            export.exportExcel(fileName, fileName, columnNames, columns, list, response, ExportExcelUtil.EXCEL_FILE_2003);
        }
    }

    @GetMapping(value = "/everyday/buy/export")
    public void exportStatistics(HttpServletResponse response, String payDate) {
        payDate = UF.toString(payDate);
        List<EverydayBuyGoldBean> data = productOrderService.queryEverydayBuyGoldRecords(payDate);
        if(data != null && data.size() > 0){
            String[] columnNames = { "序号", "日期","买金总克重（克）", "买金总金额（元）"};
            String [] columns = {"index",  "payDate", "payGram", "payAmount"};
            String fileName = "买金核算总表";
            int index = 1;
            for (EverydayBuyGoldBean bean : data) {
                bean.setIndex(index);
                index++;
            }
            ExportExcelController<EverydayBuyGoldBean> export = new ExportExcelController<EverydayBuyGoldBean>();
            export.exportExcel(fileName, fileName, columnNames, columns, data, response, ExportExcelUtil.EXCEL_FILE_2003);
        }
    }

    @GetMapping(value = "/trade/info")
    public SerializeObject<MemberDetailBean> getMemberTradeInfo(String memberId) {
        memberId = UF.toString(memberId);
        return new SerializeObject<MemberDetailBean>(ResultType.NORMAL, productOrderService.getMemberTradeInfo(memberId));
    }

    @GetMapping(value = "/rfm/list")
    public SerializeObject<DataTable<RFMLabelBean>> list(int pageNum, int pageSize, String startDate, String endDate) {
        startDate = UF.toString(startDate);
        endDate = UF.toString(endDate);
        int total = productOrderService.queryRFMLabelCount();
        if (total > 0) {
            int offset = PaginationUtil.getOffset(pageNum, pageSize);
            int size = PaginationUtil.getPageSize(pageSize);
            List<RFMLabelBean> list = productOrderService.queryRFMLabelList(startDate, endDate, offset, size);
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<RFMLabelBean>(pageNum, pageSize, total, list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<RFMLabelBean>(pageNum, pageSize, total, new ArrayList<RFMLabelBean>()));
    }

    private static Logger logger = LoggerFactory.getLogger(ProductOrderController.class);

    @RequestMapping(value = "/validation", method = POST)
    public SerializeObject validate(String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return new SerializeObjectError("00000002");
        }
        ProductOrderBean productOrderBean = productOrderService.findByOrderId(orderId);
        if (productOrderBean == null || StringUtils.isBlank(productOrderBean.getProductId())) {
            return new SerializeObjectError("00000003");
        }
        SerializeObject<ProductFindBean> obj = productService.queryProductById(productOrderBean.getProductId());
        if(null == obj || obj.getCode() != ResultType.NORMAL) {
            return new SerializeObjectError("17000601");
        }
        ProductFindBean productBean = obj.getData();
        if (productBean.getShelfState() == 2) {
            return new SerializeObjectError("17000720");
        }
        //LocalDateTime upTime = UF.getDate(productBean.getUpTimeString());
        long effectiveDay = Long.parseLong(productBean.getEffectiveDay());
        if (effectiveDay > 0) {
            LocalDateTime downTime = UF.getDate(productBean.getStopTimeString());
            if (LocalDateTime.now().isAfter(downTime)) {
                return new SerializeObjectError("17000720");
            }
        }
        if (productBean.getRaiseGram().doubleValue() > 0) {
            double toRasizeGram = 0;
            if (productBean.getToRaiseGram() != null) {
                toRasizeGram = productBean.getToRaiseGram().doubleValue();
            }
            SerializeObject<List<DataDictionaryBean>> beans = dataDictionaryService.findListByClassification(GOLD_WEIGHT_RANGE, 1);
            if (beans == null || beans.getData() == null || beans.getData().size() != 2) {
                return new SerializeObjectError("17000719");
            }
            double value0 = Double.parseDouble(beans.getData().get(0).getItemValue());
            double value1 = Double.parseDouble(beans.getData().get(1).getItemValue());
            if (value0 > value1) {
                double totalGram = productBean.getRaiseGram().doubleValue() * value0/100;
                if ((toRasizeGram+productOrderBean.getAmount().doubleValue()) > totalGram) {
                    return new SerializeObjectError("17000719");
                }
            } else {
                double totalGram = productBean.getRaiseGram().doubleValue() * value1/100;
                if ((toRasizeGram+productOrderBean.getAmount().doubleValue()) > totalGram) {
                    return new SerializeObjectError("17000719");
                }
            }
        }
        return new SerializeObject(ResultType.NORMAL, "00000001");
    }

    @RequestMapping(value = "/total", method = GET)
    public SerializeObject<List<TradeTotalAmountBean>> listTotal(int timeType, String startDate, String endDate, String[] channelIds) {
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<TradeTotalAmountBean> entity = productOrderService.listTradeAmountStatistics(timeType, startDate, endDate, channels);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }


    @RequestMapping(value = "/total/trade", method = GET)
    public SerializeObject<List<TradeTotalStatisticsBean>> listTradeTotal(int timeType, String startDate, String endDate, String[] channelIds,Integer[] productType) {
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<Integer> productTypes = null;
        if (productType != null && productType.length > 0) {
            productTypes = new ArrayList<>();
            for (Integer pro : productType) {
                productTypes.add(pro);
            }
        }
        List<TradeTotalStatisticsBean> entity = productOrderService.listTradeTotalStatistics(timeType, startDate, endDate, channels,productTypes);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/k", method = GET)
    public SerializeObject<List<KValueBean>> getKLine(String searchDate) {
        if (StringUtils.isBlank(searchDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            searchDate = dateFormat.format(Calendar.getInstance().getTime());
        }
        List<KValueBean> entity = productOrderService.listKValue(searchDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/avg", method = GET)
    public SerializeObject<List<TradeAverageValueBean>> listAvg(int timeType, String startDate, String endDate, String[] channelIds) {
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<TradeAverageValueBean> entity = productOrderService.listAvgValueStatistics(timeType, startDate, endDate, channels);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/future", method = GET)
    public SerializeObject<List<TradeFutureValueBean>> listFuture(String startDate, String endDate, String[] channelIds) {
        List<String> channels = null;
        if (channelIds != null && channelIds.length > 0) {
            channels = new ArrayList<String>();
            for (String channelId : channelIds) {
                channels.add(channelId);
            }
        }
        List<TradeFutureValueBean> entity = productOrderService.listTradeFutureValueStatistics(startDate, endDate, channels);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/total/open/position", method = GET)
    public SerializeObject<List<OpenPositionTotalBean>> listTotalOpenPosition(String startDate, String endDate) {
        List<OpenPositionTotalBean> entity = productOrderService.listOpenPositionTotalStatistics(startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/total/expired", method = GET)
    public SerializeObject<List<OpenPositionTotalBean>> listTotalExpired(String startDate, String endDate) {
        List<OpenPositionTotalBean> entity = productOrderService.listExpiredStatistics(startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/exchange/gold/amount", method = GET)
    public SerializeObject<List<OpenPositionTotalBean>> listExpiredAmountStatistics(int timeType, String startDate, String endDate, int searchType) {
        List<OpenPositionTotalBean> entity = productOrderService.listExpiredAmountStatistics(timeType, startDate, endDate, searchType);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/avg/open/position", method = GET)
    public SerializeObject<List<OpenPositionPastBean>> listAvgOpenPosition(String startDate, String endDate) {
        List<OpenPositionPastBean> entity = productOrderService.listOpenPositionAvgStatistics(startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/transaction/weight", method = GET)
    public SerializeObject<List<OpenPositionTotalBean>> listTransactionWeight(int payType, String startDate, String endDate) {
        List<OpenPositionTotalBean> entity = productOrderService.listTransactionWeightStatistics(payType, startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    @RequestMapping(value = "/gold/record", method = GET)
    public SerializeObject<List<OpenPositionTotalBean>> listGoldRecord(int timeType, String startDate, String endDate) {
        List<OpenPositionTotalBean> entity = productOrderService.listGoldRecordStatistics(timeType, startDate, endDate);
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }
    /**
     * 根据ID查找信息
     * @param id		    ID
     * @return			    记录集
     */
    @RequestMapping(value = "{id}", method = GET)
    public SerializeObject<ProductOrderBean> find(@PathVariable String id) {
        if(StringUtils.isBlank(id)) {
            return new SerializeObjectError("00000002");
        }
        ProductOrderBean entity = productOrderService.findById(id);
        if(null == entity || StringUtils.isBlank(entity.getId())) {
            return new SerializeObjectError("00000003");
        }

        if(ProductOrderPayStatus.WAIT.getValue().equals(entity.getPayStatus())) {
            // 如果是待支付，列出剩余时间
            entity.setStopPayTimeSecond(Duration.between(UF.getDateTime(), UF.getDateTime(entity.getStopPayTimeString())).getSeconds());
            if(entity.getStopPayTimeSecond() <= 0) {
                entity.setStopPayTimeSecond(0);
            }
        }
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    /**
     * 根据流水号, 查找对象
     * @param orderId	流水号
     * @return			记录集
     */
    @RequestMapping(value = "findByOrderId", method = GET)
    public SerializeObject<ProductOrderBean> findByOrderId(String orderId) {
        if(StringUtils.isBlank(orderId)) {
            return new SerializeObjectError("00000002");
        }
        ProductOrderBean entity = productOrderService.findByOrderId(orderId);
        if(null == entity || StringUtils.isBlank(entity.getId())) {
            return new SerializeObjectError("00000003");
        }

        if(ProductOrderPayStatus.WAIT.getValue().equals(entity.getPayStatus())) {
            // 如果是待支付，列出剩余时间
            entity.setStopPayTimeSecond(Duration.between(UF.getDateTime(), UF.getDateTime(entity.getStopPayTimeString())).getSeconds());
            if(entity.getStopPayTimeSecond() <= 0) {
                entity.setStopPayTimeSecond(0);
            }
        }
        return new SerializeObject<>(ResultType.NORMAL, entity);
    }

    /**
     * 发起投资申请
     * @param accessToken		登录成功后分配的Key
     * @param entity		    记录集
     * @param payPassword		交易密码
     * @return				    是否操作成功
     */
    @RequestMapping(method = POST)
    public SerializeObject update(@RequestHeader String accessToken, ProductOrderBean entity, String payPassword) {
        if(null == entity || StringUtils.isBlank(entity.getProductId()) || null == entity.getBuyType()) {
            return new SerializeObjectError("00000002");
        }
        //新版本提单上线，老版本生成待支付停用（2018-12-17）
        if(null != entity) {
            return new SerializeObjectError("170020455");
        }
        // 购买类型 1:按克重 2:按金额
        if(entity.getBuyType() == 1 && (BigDecimalUtil.isZeroOrNull(entity.getAmount()) || entity.getAmount().compareTo(BigDecimal.ZERO) <= 0)) {
            return new SerializeObjectError("00000002");
        }
        if(entity.getBuyType() == 2 && (BigDecimalUtil.isZeroOrNull(entity.getActualAmount()) || entity.getActualAmount().compareTo(BigDecimal.ZERO) <= 0)) {
            return new SerializeObjectError("00000002");
        }
        String memberId = LoginHelper.getLoginId();
        if(StringUtils.isBlank(memberId)) {
            return new SerializeObjectError("00000102");
        }
        entity.setMemberId(memberId);

        // 如果是金柚宝转入，验证交易密码
        if(PayType.TURN_INTO.getValue().equals(entity.getPayType())) {
            // 交易密码验证
            SerializeObject obj = memberUserService.validatePayPassword(memberId, payPassword);
            if (null == obj || obj.getCode() != ResultType.NORMAL) {
                SerializeObject paramBean  = rateSettingsService.get(RateKeyEnum.TRADE_PASSWORD.getKey());
                if (paramBean != null && paramBean.getData() != null) {
                    JSONObject json = JSON.parseObject(JSONObject.toJSONString(paramBean.getData()));
                    int isLimited = json.getIntValue("isLimited");
                    int wrongTimes = json.getIntValue("wrongTimes");
                    int minutes = json.getIntValue("minutes");
                    if (isLimited == 1) {
                        SerializeObject<MemberUserBean> memberBean = memberUserService.findById(memberId);
                        if (null == memberBean || memberBean.getData() == null) {
                            return new SerializeObjectError("00000102");
                        }
                        MemberUserBean memberUserBean = memberBean.getData();
                        if (isLimited == 1 && memberUserBean.getTrdpassdStatus() == 1) {
                            SerializeObjectError result = new SerializeObjectError<>("17002034");
                            String msg = String.format(result.getMsg(), wrongTimes, minutes);
                            result.setMsg(msg);
                            return result;
                        }
                        int actualWrongTimes = memberUserBean.getTrdpassdWrongTimes();
                        actualWrongTimes++;
                        int status = 0;
                        if (wrongTimes <= actualWrongTimes) {
                            status = 1;
                        }
                        memberUserService.modifyWrongTimes(memberUserBean.getId(), 2, actualWrongTimes, status);
                        if (wrongTimes <= actualWrongTimes) {
                            MemberPasswordStatusMQ mq = new MemberPasswordStatusMQ();
                            mq.setMemberId(memberUserBean.getId());
                            mq.setType(2);
                            amqpTemplate.convertAndSend(QUEUE_MEMBER_PASSWORD_STATUS_DELAY, mq, new DelayMessagePostProcessor(minutes * 60 * 1000));

                            SerializeObjectError result = new SerializeObjectError<>("17002034");
                            String msg = String.format(result.getMsg(), wrongTimes, minutes);
                            result.setMsg(msg);
                            return result;
                        }
                    }
                }
                info("交易密码验证失败。 memberId = " + memberId);
                return obj;
            }
            memberUserService.modifyWrongTimes(memberId, 2, 0, 0);
        }
        return new SerializeObject<>(ResultType.NORMAL, "00000001", productOrderService.save(entity));
    }

    /**
     * 根据当前登录用户查询数据
     * @param accessToken	    登录成功后分配的Key
     * @param order		        排序
     * @param page		        分页
     * @param payStatus		    支付状态  1:待支付 2:已支付 3:已过期
     * @param status		    产品状态  1:未到期 2:已到期
     * @param addTimeMinString	最小投资时间(yyyy-MM-dd)
     * @param addTimeMaxString  最大投资时间(yyyy-MM-dd)
     * @return			        分页数据
     */
    @RequestMapping(value = "queryByMemberId", method = GET)
    public SerializeObject<DataTable<ProductOrderBean>> queryByMemberId(@RequestHeader String accessToken, Order order, Page page,
                                                                        Integer payStatus, Integer status, String addTimeMinString, String addTimeMaxString) {
        if(page.getPageSize() <= 0) {
            page.setPageSize(config.getPageSize());
        }
        if(null == payStatus || payStatus < 0) {
            payStatus = 0;
        }
        if(null == status || status < 0) {
            status = 0;
        }
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        String memberId = LoginHelper.getLoginId();
        if(StringUtils.isBlank(memberId)) {
            return new SerializeObjectError<>("00000102");
        }

        List<Integer> typeList = null;
        if(null != payStatus && !payStatus.equals(ProductOrderPayStatus.WAIT.getValue())) {
            // 状态不是待支付时，屏蔽活期订单
            typeList = new ArrayList<>();
            typeList.add(ProductTypeEnum.REGULAR.getType());
            typeList.add(ProductTypeEnum.ACTIVITY.getType());
            typeList.add(ProductTypeEnum.NOVICE.getType());
        }

        DataTable<ProductOrderBean> dataTable = productOrderService.query(order.getOrder(), order.getSort(), page.getPageNum(), page.getPageSize(), typeList, payStatus, status,
                null, null, null, addTimeMin, addTimeMax, memberId, null, null, null, null, null);
        return new SerializeObject<>(ResultType.NORMAL, dataTable);
    }

    /**
     * 根据产品ID查找投资记录
     * @param order		        排序
     * @param page		        分页
     * @param productId		    产品ID
     * @return			        分页数据
     */
    @RequestMapping(value = "queryByProductId", method = GET)
    public SerializeObject<DataTable<ProductOrderSummaryBean>> queryByProductId(Order order, Page page, String productId) {
        if(page.getPageSize() <= 0) {
            page.setPageSize(config.getPageSize());
        }
        SerializeObject<ProductFindBean> productBean = productService.queryProductById(productId);
        int type = 1;
        if (productBean != null && productBean.getData() != null) {
            ProductFindBean product = productBean.getData();
            type = product.getType();
        }
        //DataTable<ProductOrderSummaryBean> dataTable = productOrderService.queryByProductId(order.getOrder(), order.getSort(), page.getPageNum(), page.getPageSize(), productId);

        //return new SerializeObject<>(ResultType.NORMAL, dataTable);
        int total = productOrderService.countByProductId(productId, type);
        page.setTotal(total);
        if (total > 0) {
            List<ProductOrderSummaryBean> list = productOrderService.queryByProductId(PaginationUtil.getOffset(page.getPageNum(), page.getPageSize()), PaginationUtil.getPageSize(page.getPageSize()), productId, type);
            return new SerializeObject<>(ResultType.NORMAL, new DataTable<ProductOrderSummaryBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), list));
        }
        return new SerializeObject<>(ResultType.NORMAL, new DataTable<ProductOrderSummaryBean>(page.getPageNum(), page.getPageSize(), page.getTotal(), new ArrayList<ProductOrderSummaryBean>()));
    }

    /**
     * 查询数据
     * @param accessToken	    登录成功后分配的Key
     * @param order		        排序
     * @param page		        分页
     * @param payStatus		    支付状态  1:待支付 2:已支付 3:已过期
     * @param status		    产品状态  1:未到期 2:已到期
     * @param amountMin		    最小购买克重
     * @param amountMax		    最大购买克重
     * @param addTimeMinString  最小投资时间(yyyy-MM-dd)
     * @param addTimeMaxString  最大投资时间(yyyy-MM-dd)
     * @param memberId		    会员ID
     * @param memberName	    会员名称
     * @param memberMobile	    会员手机
     * @param keyword		    关键字
     * @return			        分页数据
     */
    @RequestMapping(method = GET)
    public SerializeObject<DataTable<ProductOrderBean>> query(@RequestHeader String accessToken, Order order, Page page, Integer payStatus, Integer status,
                                                              BigDecimal amountMin, BigDecimal amountMax, String addTimeMinString, String addTimeMaxString,
                                                              String memberId, String memberName, String memberMobile, String keyword) {
        if(page.getPageSize() <= 0) {
            page.setPageSize(config.getPageSize());
        }
        if(null == payStatus || payStatus < 0) {
            payStatus = 0;
        }
        if(null == status || status < 0) {
            status = 0;
        }
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        keyword = UF.toString(keyword);

        DataTable<ProductOrderBean> dataTable = productOrderService.query(order.getOrder(), order.getSort(), page.getPageNum(), page.getPageSize(), null, payStatus, status,
                null, amountMin, amountMax, addTimeMin, addTimeMax, memberId, memberName, memberMobile, null, keyword, null);
        return new SerializeObject<>(ResultType.NORMAL, dataTable);
    }

    /**
     * 查询数据(定期投资记录)
     * @param accessToken	    登录成功后分配的Key
     * @param order		        排序
     * @param page		        分页
     * @param payStatus		    支付状态  1:待支付 2:已支付 3:已过期
     * @param status		    产品状态  1:未到期 2:已到期
     * @param amountMin		    最小购买克重
     * @param amountMax		    最大购买克重
     * @param addTimeMinString  最小投资时间(yyyy-MM-dd)
     * @param addTimeMaxString  最大投资时间(yyyy-MM-dd)
     * @param memberId		    会员ID
     * @param memberName	    会员名称
     * @param memberMobile	    会员手机
     * @param keyword		    关键字
     * @return			        分页数据
     */
    @RequestMapping(value = "queryByRegular", method = GET)
    public SerializeObject<DataTable<ProductOrderBean>> queryByRegular(@RequestHeader String accessToken, Order order, Page page, Integer payStatus, Integer status,
                                                              BigDecimal amountMin, BigDecimal amountMax, String addTimeMinString, String addTimeMaxString,
                                                              String memberId, String memberName, String memberMobile, String keyword, String channelId) {
        if(page.getPageSize() <= 0) {
            page.setPageSize(config.getPageSize());
        }
        if(null == payStatus || payStatus < 0) {
            payStatus = 0;
        }
        if(null == status || status < 0) {
            status = 0;
        }
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        keyword = UF.toString(keyword);
        List<Integer> typeList = new ArrayList<>();
        typeList.add(ProductTypeEnum.REGULAR.getType());
        typeList.add(ProductTypeEnum.ACTIVITY.getType());
        typeList.add(ProductTypeEnum.NOVICE.getType());
        channelId = UF.toString(channelId);
        DataTable<ProductOrderBean> dataTable = productOrderService.query(order.getOrder(), order.getSort(), page.getPageNum(), page.getPageSize(), typeList, payStatus, status,
                null, amountMin, amountMax, addTimeMin, addTimeMax, memberId, memberName, memberMobile, null, keyword, channelId);
        return new SerializeObject<>(ResultType.NORMAL, dataTable);
    }

    @RequestMapping(value = "/queryByRegular/export", method = GET)
    public void exportOrder(HttpServletResponse response, Order order, Integer payStatus, Integer status,BigDecimal amountMin, BigDecimal amountMax, String addTimeMinString, String addTimeMaxString,
                                                                       String memberId, String memberName, String memberMobile, String keyword, String channelId) {
        if(null == payStatus || payStatus < 0) {
            payStatus = 0;
        }
        if(null == status || status < 0) {
            status = 0;
        }
        LocalDateTime addTimeMin = null;
        LocalDateTime addTimeMax = null;
        if(StringUtils.isNotBlank(addTimeMinString)) {
            addTimeMin = UF.getDate(addTimeMinString);
        }
        if(StringUtils.isNotBlank(addTimeMaxString)) {
            addTimeMax = UF.getDate(addTimeMaxString);
        }
        keyword = UF.toString(keyword);
        List<Integer> typeList = new ArrayList<>();
        typeList.add(ProductTypeEnum.REGULAR.getType());
        typeList.add(ProductTypeEnum.ACTIVITY.getType());
        typeList.add(ProductTypeEnum.NOVICE.getType());
        channelId = UF.toString(channelId);
        List<ProductOrderBean> list = productOrderService.query(order.getOrder(), order.getSort(), typeList, payStatus, status,
                null, amountMin, amountMax, addTimeMin, addTimeMax, memberId, memberName, memberMobile, null, keyword, channelId);
        String[] columnNames = { "序号", "流水号","手机号", "用户姓名", "渠道名称", "产品名称", "产品期限", "年化收益%", "加息利率%", "加息券编号", "红包返现(元)", "现金红包编号",
            "购买克重(克)", "购买金价(元/克)", "支付金额(元)", "手续费(元)", "预计收益(克)", "加息奖励(元)", "产品状态", "投资时间", "计息时间", "到期时间"};
        String [] columns = {"index",  "orderId", "memberMobile", "memberName", "channelName", "productName", "investDay", "yearsIncome", "couponIncreaseRate", "couponIncreaseId",
                "couponRedAmount", "couponRedId", "amount", "goldPrice", "actualAmount", "fee", "incomeAmount", "couponIncreaseMoney", "status", "addTimeString", "startTimeString", "endTimeString"};
        String fileName = "定期投资表";
        List<RegularOrderExportBean> orders = new ArrayList<RegularOrderExportBean>();
        int index = 1;
        for (ProductOrderBean bean : list) {
            RegularOrderExportBean exportOrder = new RegularOrderExportBean();
            exportOrder.setIndex(index);
            exportOrder.setOrderId(bean.getOrderId());
            exportOrder.setMemberMobile(bean.getMemberMobile());
            exportOrder.setMemberName(bean.getMemberName());
            exportOrder.setChannelName(bean.getChannelName());
            exportOrder.setProductName(bean.getProductName());
            exportOrder.setInvestDay(bean.getInvestDay());
            exportOrder.setYearsIncome(bean.getYearsIncome());
            if (bean.getProductOrderFeeBean() != null) {
                exportOrder.setCouponIncreaseRate(String.valueOf(bean.getProductOrderFeeBean().getCouponIncreaseRate()));
                if (StringUtils.isNotBlank(bean.getProductOrderFeeBean().getCouponIncreaseId())) {
                    exportOrder.setCouponIncreaseId(bean.getProductOrderFeeBean().getCouponIncreaseId());
                } else {
                    exportOrder.setCouponIncreaseId("N/A");
                }
                exportOrder.setCouponRedAmount(String.valueOf(bean.getProductOrderFeeBean().getCouponRedAmount()));
                if (StringUtils.isNotBlank(bean.getProductOrderFeeBean().getCouponRedId())) {
                    exportOrder.setCouponRedId(bean.getProductOrderFeeBean().getCouponRedId());
                } else {
                    exportOrder.setCouponRedId("N/A");
                }
                exportOrder.setCouponIncreaseMoney(String.valueOf(bean.getProductOrderFeeBean().getCouponIncreaseMoney()));
            } else {
                exportOrder.setCouponIncreaseRate("N/A");
                exportOrder.setCouponIncreaseId("N/A");
                exportOrder.setCouponRedAmount("N/A");
                exportOrder.setCouponRedId("N/A");
                exportOrder.setCouponIncreaseMoney("N/A");
            }
            exportOrder.setAmount(bean.getAmount());
            exportOrder.setGoldPrice(bean.getGoldPrice());
            exportOrder.setActualAmount(bean.getActualAmount());
            exportOrder.setFee(bean.getFee());
            exportOrder.setIncomeAmount(bean.getIncomeAmount());
            if (bean.getStatus() == 1) {
                exportOrder.setStatus("未到期");
            } else if(bean.getStatus() == 2) {
                exportOrder.setStatus("已到期");
            }
            exportOrder.setAddTimeString(bean.getAddTimeString());
            exportOrder.setStartTimeString(bean.getStartTimeString());
            exportOrder.setEndTimeString(bean.getEndTimeString());
            index++;
            orders.add(exportOrder);
        }
        ExportExcelController<RegularOrderExportBean> export = new ExportExcelController<RegularOrderExportBean>();
        export.exportExcel(fileName, fileName, columnNames, columns, orders, response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    /**
     * 选择红包、加息券。 （用在添加投资记录之后，支付之前）
     * @param accessToken	        登录成功后分配的Key
     * @param orderId               投资记录流水号
     * @param couponRedId           红包ID
     * @param couponIncreaseId      加息券ID
     * @return                      操作结果
     */
    @RequestMapping(value = "chooseCoupon", method = POST)
    public SerializeObject chooseCoupon(@RequestHeader String accessToken, String orderId, String couponRedId, String couponIncreaseId) {
        if(StringUtils.isBlank(orderId)) {
            return new SerializeObjectError("00000002");
        }
        String memberId = LoginHelper.getLoginId();
        if(StringUtils.isBlank(memberId)) {
            return new SerializeObjectError<>("00000102");
        }

        productOrderService.chooseCoupon(memberId, orderId, couponRedId, couponIncreaseId);
        return new SerializeObject<>(ResultType.NORMAL);
    }

    /**
     * 统计投资次数
     * @param accessToken           登录成功后分配的Key
     * @return                      操作结果
     */
    @GetMapping("successAmount")
    public SerializeObject successAmount(@RequestHeader String accessToken) {
        String memberId = LoginHelper.getLoginId();
        if(StringUtils.isBlank(memberId)) {
            return new SerializeObjectError<>("00000102");
        }

        List<Integer> typeList = new ArrayList<>();
        typeList.add(ProductTypeEnum.REGULAR.getType());
        typeList.add(ProductTypeEnum.ACTIVITY.getType());
        typeList.add(ProductTypeEnum.CURRENT.getType());
        typeList.add(ProductTypeEnum.NOVICE.getType());

        DataTable<ProductOrderBean> dataTable = productOrderService.query(null, null, 1, 1, typeList,
                ProductOrderPayStatus.COMPLETE.getValue(), null,null, null, null,
                null, null, memberId, null, null, null, null, null);

        return new SerializeObject<>(ResultType.NORMAL, dataTable.getPage().getTotal());
    }

    /**
     *
     * 查询会员已购买某类型产品数量
     * @param memberId
     * @return
     */
    @GetMapping("findRegularBuyCount")
    public SerializeObject<Integer> findRegularBuyCount(String memberId) {
        int total = productOrderService.findRegularBuyCount(memberId);
        return new SerializeObject<>(ResultType.NORMAL, total);
    }

    /**
     * 查询会员已购买某类型活动产品数量
     * @param memberId
     * @return
     */
    @GetMapping("findRegularActivityBuyCount")
    public SerializeObject<Integer> findRegularActivityBuyCount(String memberId) {
        int total = productOrderService.findRegularActivityBuyCount(memberId);
        return new SerializeObject<>(ResultType.NORMAL, total);
    }

    /**
     *查询用户黄金购买记录
     * @param pageNum
     * @param pageSize
     * @param addTimeMinString  投资期限最小值
     * @param addTimeMaxString  投资期限最大值
     * @param startDate  结束时间最小值
     * @param endDate  结束时间最大值
     * @return
     */
    @RequestMapping(value = "queryInfoByMemberId", method = GET)
    public SerializeObject<DataTable<ProductOrderBean>> queryInfoByMemberId(
                                                                        int pageNum, int pageSize, String addTimeMinString, String addTimeMaxString,
                                                                        String startDate, String endDate,String memberId) {
        if(pageSize <= 0) {
            pageSize = config.getPageSize();
        }
        return new SerializeObject<>(ResultType.NORMAL, productOrderService.queryInfoByMemberId(pageNum,pageSize,addTimeMinString,
                addTimeMaxString,startDate,endDate,memberId));
    }

    /**
     * 个人黄金购买记录
     *
     * @return
     */
    @RequestMapping(value = "/export", method = GET)
    public void export(HttpServletResponse response,
                       String addTimeMinString, String addTimeMaxString,
                       String startDate, String endDate,String memberId) {
        String[] columnNames = {"序号", "产品名称", "产品类型","产品期限（天）","产品年化收益", "支付金额（元）", "购买黄金克重（克）", "购买时金价（元/克）","是否到期", "投资时间","到期时间"};
        String[] columns = {"index", "productName", "productType","investDay","productOrderYearsIncome", "actualAmount", "amount", "goldPrice","productStatus", "addTimeString","endTimeString"};
        String fileName = "黄金交易记录";
        DataTable<ProductOrderBean> productOrderBeanDataTable = productOrderService.queryInfoByMemberId(1,Integer.MAX_VALUE,addTimeMinString,
                addTimeMaxString,startDate,endDate,memberId);

        ExportExcelController<ProductOrderExportBean> export = new ExportExcelController<>();
        export.exportExcel(fileName, fileName, columnNames, columns,
                wrapPutGoldBeanData(productOrderBeanDataTable.getDataList()), response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    private List<ProductOrderExportBean> wrapPutGoldBeanData(List<ProductOrderBean> list) {
        int index = 1;
        List<ProductOrderExportBean> productOrderExportBeanList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)){
            for (ProductOrderBean bean : list) {
                ProductOrderExportBean productOrderExportBean = new ProductOrderExportBean();
                BeanUtils.copyProperties(bean,productOrderExportBean);
                productOrderExportBean.setIndex(index++);
                productOrderExportBean.setProductType(bean.getType()==3?"流动金":bean.getType()==4?"稳赢金":bean.getType()==1?"新手特权金":null);
                productOrderExportBean.setProductStatus(bean.getStatus()==1?"未到期":"已到期");
                productOrderExportBean.setProductOrderYearsIncome(bean.getYearsIncome()+"%");
                if (bean.getType()==3){
                    productOrderExportBean.setProductStatus("N/A");
                    productOrderExportBean.setEndTimeString("N/A");
                }
                productOrderExportBeanList.add(productOrderExportBean);
            }
        }
        return productOrderExportBeanList;
    }
}
